import store from '@/store'
import vm from '@/main'

/* eslint-disable no-undef */
// const globalUrl = 'http://47.97.98.33/'
const fileUrl = 'http://171.223.209.207:9990'

function getUuid (len, radix) {
    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
    var uuid = [], i
    radix = radix || chars.length

    if (len) {
        // Compact form
        for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
    } else {
        // rfc4122, version 4 form
        var r

        // rfc4122 requires these characters
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
        uuid[14] = '4'

        // Fill in random data.  At i==19 set the high bits of clock sequence as
        // per rfc4122, sec. 4.1.5
        for (i = 0; i < 36; i++) {
            if (!uuid[i]) {
                r = 0 | Math.random() * 16
                uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]
            }
        }
    }

    return uuid.join('')
}

function getUrlParams (name) {
    const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
    const r = window.location.search.substr(1).match(reg)
    if (r != null) return unescape(r[2])
    return null
}

function getType (obj) {
    //tostring会返回对应不同的标签的构造函数
    let type = Object.prototype.toString.call(obj)
    let map = {
        '[object Boolean]': 'boolean',
        '[object Number]': 'number',
        '[object String]': 'string',
        '[object Function]': 'function',
        '[object Array]': 'array',
        '[object Date]': 'date',
        '[object RegExp]': 'regExp',
        '[object Undefined]': 'undefined',
        '[object Null]': 'null',
        '[object Object]': 'object'
    }
    let isElement = false
    if (typeof Element != 'undefined') {
        isElement = obj instanceof Element
    }
    if (isElement) {
        return 'element'
    }
    return map[type]
}

function formatDate (dateStr, formatStr) {
    var fmt = null
    if (!dateStr) {
        return ''
    }
    var date = dateStr
    if (getType(dateStr) !== 'date') {
        date = new Date(dateStr)
    }
    var reg = {
        'M+': date.getMonth() + 1,                   //月份
        'd+': date.getDate(),                        //日
        'h+': date.getHours(),                       //小时
        'm+': date.getMinutes(),                     //分
        's+': date.getSeconds(),                     //秒
        'q+': Math.floor((date.getMonth() + 3) / 3), //季度
        'S': date.getMilliseconds(),                 //毫秒
        'w+': date.getDay()                          //周几
    }
    var arr = [], arr1 = [], arr2 = []
    if (getType(dateStr) === 'string') {
        if (dateStr.indexOf('T') != -1) {
            arr = dateStr.split('T')
            arr1 = arr[0].split('-')
            arr2 = arr[1].split('.')
            arr2 = arr2[0].split(':')
            reg['M+'] = arr1[1]                        //月份
            reg['d+'] = arr1[2]                        //日
            reg['h+'] = arr2[0]                        //小时
            reg['m+'] = arr2[1]                        //分
            reg['s+'] = arr2[2]                        //秒
        }
    }
    if (/(y+)/.test(formatStr)) {
        fmt = formatStr.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
    }
    for (var k in reg) {
        if (!fmt) {
            fmt = formatStr
        }
        if (new RegExp('(' + k + ')').test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (reg[k]) : (('00' + reg[k]).substr(('' + reg[k]).length)))
        }
    }
    return fmt
}

function formatFileSize (fileSize) {
    var temp
    if (fileSize < 1024) {
        return fileSize + 'B'
    } else if (fileSize < (1024 * 1024)) {
        temp = fileSize / 1024
        temp = temp.toFixed(2)
        return temp + 'KB'
    } else if (fileSize < (1024 * 1024 * 1024)) {
        temp = fileSize / (1024 * 1024)
        temp = temp.toFixed(2)
        return temp + 'MB'
    } else {
        temp = fileSize / (1024 * 1024 * 1024)
        temp = temp.toFixed(2)
        return temp + 'GB'
    }
}

function isPic (type) {
    type = type.toUpperCase()
    return type.indexOf('JPG') !== -1 || type.indexOf('PNG') !== -1 || type.indexOf('JPEG') !== -1
}

function parseList (list, ListId, ParentId, root) {
    ListId = ListId || 'ListItemId'
    ParentId = ParentId || 'ParentId'
    root = root || '-1'
    var map = {}
    list.forEach(function (item) {
        if (item.isLeaf) {
            item.hasChildren = !item.isLeaf
        }
        if(!map[item[ListId]]) {
            map[item[ListId]] = item
        }
    })
    list.forEach(function (item) {
        map[item[ParentId]] = map[item[ParentId]] || {}
        map[item[ParentId]].children ? map[item[ParentId]].children.push(item) : map[item[ParentId]].children = [item]
    })
    if (!(root in map)) {
        map[root] = {
            children: []
        }
    }
    return map[root].children
}

function treeToList (tree, callBack) {
    const result = []
    let stack = vm._.clone(tree)
    let item = stack.shift()
    while (item) {
        result.push(item)
        callBack && callBack(item)
        if (item.children && item.children.length) {
            stack = stack.concat(item.children)
        }
        item = stack.shift()
    }
    return result
}

// 通过迭代循环获取当前节点在树结构的位置
// getItemOfTreeArr(data, 'uuid', row.uuid)
function getItemOfTreeArr (tree, fieldName, fieldValue) {
    const data = tree
    // 找出树中当前节点
    let level = 0 // 层级
    const stack = [] // 保存树节点
    const stackIndex = [] // 保存当前层级的索引
    const stackList = [] // 保存每层的列表
    stackIndex[level] = 0
    stackList.push(data)
    while (stackList[level]) {
        let find = false
        let deep = false // 是否进入下层循环
        // 遍历当前层级列表查找
        for (let i = stackIndex[level], len = stackList[level].length; i < len; i++) {
            let item = stackList[level][i]
            // 把当前元素入栈
            stack.push(item)
            // 找到则结束
            if (item[fieldName] === fieldValue) {
                find = true
                // 同级元素出栈
                stack.pop()
                // 把当前元素压入栈
                stack.push(item)
                break
            }
            // 如果有子级，则继续往下层找
            if (item.children && item.children.length) {
                level++
                stackList.push(item.children)
                item = item.children[i]
                stackIndex[level] = 0
                // 退出当前层级循环，进入下层循环
                deep = true
                break
            }
            // 没有下级，则往下一元素找，保存层级位置，如果下级没找到，再回到当前层，从当前位置后面开始继续找
            stackIndex[level] = i
            // 如果当前元素不是要找的元素，则出栈
            stack.pop()
        }
        // 若已找到，则退出循环
        if (find) {
            break
        }
        // 未进入下层，则表示找完当前层级，仍未找到
        if (!deep) {
            // 返回上级，继续往下一元素找
            stackIndex.pop()
            stackList.pop()
            stack.pop()
            level--
            stackIndex[level] += 1
        }
    }
    return stack
}

function autoClick (url) {
    const elink = document.createElement('a')
    elink.style.display = 'none'
    elink.target = '_blank'
    elink.href = url
    document.body.appendChild(elink)
    const event = document.createEvent('MouseEvents')
    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
    elink.dispatchEvent(event)
    document.body.removeChild(elink)
}

function groupBy (array, f) {
    let groups = {}
    array.forEach( function ( o ) {
        let group = JSON.stringify( f(o) )
        groups[group] = groups[group] || []
        groups[group].push( o )
    })
    return Object.keys(groups).map( function ( group ) {
        return groups[group]
    })
}

function copyTxt (txt) {
    var textArea = document.createElement('textarea')
    textArea.style.position = 'fixed'
    textArea.style.width = 0
    textArea.style.height = 0
    textArea.value = txt
    document.body.appendChild(textArea)
    textArea.select()
    try {
        var successful = document.execCommand('copy')
        var msg = successful ? '成功复制到剪贴板' : '该浏览器不支持点击复制到剪贴板'
        alert(msg)
    } catch (err) {
        alert('该浏览器不支持点击复制到剪贴板')
    }
    document.body.removeChild(textArea)
}

function bytesToSize (sizesNum) {
    if (sizesNum === 0) return '0 KB'
    const k = 1024
    const sizes = ['KB', 'MB', 'GB']
    const i = Math.floor(Math.log(sizesNum) / Math.log(k))
    return (sizesNum / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]
}
/**
 * @param handle 要执行的函数
 * @param wait 间隔多久执行，默认300毫秒
 * @param immediate 是否立即执行，默认最后执行
 */
function debounce (handle, wait, immediate) {
    if (typeof handle !== 'function') throw new Error('handle muse be function')
    if (typeof wait === 'undefined') wait = 300
    if (typeof wait === 'boolean') {
        immediate = wait
        wait = 300
    }
    if (typeof immediate !== 'boolean') immediate = false
    let timer = null
    return function proxy (...args) {
        const me = this,
            init = immediate && !timer
        clearTimeout(timer)
        timer = setTimeout(() => {
            timer = null
            !immediate ? handle.call(me, ...args) : null
        }, wait)
        init ? handle.call(me, ...args) : null
    }
}
function throttle (handle, wait) {
    if (typeof handle !== 'function') throw new Error('handle must be an function')
    if (typeof wait === 'undefined') wait = 400

    let previous = 0  // 定义变量记录上一次执行时的时间
    let timer = null  // 用它来管理定时器

    return function proxy (...args) {
        let now = new Date() // 定义变量记录当前次执行的时刻时间点
        let self = this
        let interval = wait - (now - previous)

        if (interval <= 0) {
            // 此时就说明是一个非高频次操作，可以执行 handle
            clearTimeout(timer)
            timer = null
            handle.call(self, ...args)
            previous = new Date()
        } else if (!timer) {
            // 当我们发现当前系统中有一个定时器了，就意味着我们不需要再开启定时器
            // 此时就说明这次的操作发生在了我们定义的频次时间范围内，那就不应该执行 handle
            // 这个时候我们就可以自定义一个定时器，让 handle 在 interval 之后去执行
            timer = setTimeout(() => {
                clearTimeout(timer) // 这个操作只是将系统中的定时器清除了，但是 timer 中的值还在
                timer = null
                handle.call(self, ...args)
                previous = new Date()
            }, interval)
        }
    }
}

let loadingObj
function showLoading (text = '加载中...') {
    let n = 0
    let si = setInterval(() => {
        try {
            if (callbackObj) {
                callbackObj.changeLoadingState(true)
                clearInterval(si)
                si = null
            } else {
                CefSharp.BindObjectAsync('callbackObj') // 注册客户端api
            }
        } catch (error) {
            if (n++ > 10) {
                clearInterval(si)
                si = null
                loadingObj = vm.$loading({
                    fullscreen: true,
                    text
                })
            }
        }
    }, 10)
}
function hideLoading () {
    let n = 0
    let si = setInterval(() => {
        try {
            if (callbackObj) {
                callbackObj.changeLoadingState(false)
                clearInterval(si)
                si = null
            } else {
                CefSharp.BindObjectAsync('callbackObj') // 注册客户端api
            }
        } catch (e) {
            if (n++ > 11) {
                clearInterval(si)
                si = null
            }
            if (loadingObj) {
                loadingObj.close()
                loadingObj = null
            }
        }
    }, 10)
}

// 下载文件
function downloadFile (obj) {
    const blob = new Blob([obj.data])
    const reader = new FileReader()
    reader.readAsDataURL(blob)  // 转换为base64，可以直接放入a标签href
    reader.onload = function (e) {
        var elink = document.createElement('a')
        elink.download = obj.name
        elink.style.display = 'none'
        elink.href = e.target.result
        document.body.appendChild(elink)
        elink.click()
        document.body.removeChild(elink)
    }
}

// 高级搜索
function advanceSearch (url) {
    return new Promise ((resolve, reject) => {
        try{
            callbackObj.openAdvancedSearchWindow(url)
            // 高级搜索回调
            window.setAdvanceSearch = function (params) {
                // 客户端点击 “确定”还是“取消” 标志
                // alert(params)
                // 点击确定
                if (params) {
                    const searchForm = JSON.parse(localStorage.vuex).searchForm
                    // const searchForm = vm._.cloneDeep(store.state.searchForm)
                    if (searchForm) {
                        searchForm.searching = true
                        // 设置搜索状态
                        store.commit('setSearchData', searchForm)
                        resolve(searchForm)
                    }
                } else {
                    // 点击取消
                    reject('取消')
                }
            }
        } catch (e) {
            reject(e)
        }
    })
}
// 选择数据
function selectDataClient (params) {
    return new Promise ((resolve, reject) => {
        try {
            if (callbackObj) {
                callbackObj.beginSelect(JSON.stringify(params))
                // 选择数据回调
                window.confirmSelect = function (obj) {
                    const result = JSON.parse(obj)
                    try {
                        resolve(JSON.parse(result))
                    } catch (error) {
                        reject(error)
                    }
                }
            } else {
                CefSharp.BindObjectAsync('callbackObj') // 注册客户端api
            }
        } catch (error) {
            reject(error)
        }
    })
}
// 打开客户端弹窗
// getPopData 确定回调
// cancelPop 取消回调
function openAppClient (path, title, callBack, params, cancelCallBack, fn, size = 'big') {
    try{
        callBack ? (window.getPopData = callBack) : (window.getPopData = null) // 向客户端开放全局变量，让客户端在关闭弹窗时回调
        cancelCallBack ? (window.cancelPop = cancelCallBack) : (window.cancelPop = null)
        callbackObj.changeLoadingState(true) // ChangeLoadingState为客户端提供打开loading的方法
        setTimeout(() => {
            let width = null
            let height = null
            callbackObj.changeLoadingState(false) // 调用客户端api关闭loading
            if(size === 'small') {
                width = 600
                height = 350
                callbackObj.openWindow(JSON.stringify({ url: path, title, fn: fn || '', width, height })) // OpenWindow为客户端提供打开弹窗的方法
            }else if(size === 'middle') {
                width = 900
                height = 500
                callbackObj.openWindow(JSON.stringify({ url: path, title, fn: fn || '', width, height })) // OpenWindow为客户端提供打开弹窗的方法
            }else{
                callbackObj.openWindow(JSON.stringify({ url: path, title, fn: fn || '' })) // OpenWindow为客户端提供打开弹窗的方法
            }

        }, 1000)

    } catch (error) {
        callBack ? (window.getPopData = callBack) : (window.getPopData = null) // 向客户端开放全局变量，让客户端在关闭弹窗时回调
        cancelCallBack ? (window.cancelPop = cancelCallBack) : (window.cancelPop = null)
        showLoading()
        setTimeout(() => {
            showWebClient(JSON.stringify({ url: path, title, fn: fn || '' })) // OpenWindow为客户端提供打开弹窗的方法
        }, 1000)
    }
}
function showWebClient (res) {
    const params = res ? JSON.parse(res) : {}
    store.commit('setDialogParams', params)
    store.commit('setDialogVisible', true)
    hideLoading()
}
// 关闭客户端当前弹窗
function closeAppClient () {
    try{
        callbackObj.closeWindow() // 调用客户端api关闭loading
    } catch (error) {
        alert(error.toString)
    }
}
//将数据存储到客户端
function setItem (key, value) {
    try{
        const identification = '_WEB' //用于区分存储值的标识，防止与客户端键名冲突
        let str
        if(typeof value === 'object') {
            str = JSON.stringify(value)
        }else if(typeof value === 'number') {
            str = value.toString()
        }else{
            str = value
        }
        if(callbackObj) {
            callbackObj.setObj(key + identification, str)
        }
        else{
            localStorage.setItem(key + identification, str)
        }
    } catch (error) {
        alert(error.toString)
    }
}
//获取存储到客户端的数据
function getItem (key) {
    try{
        const identification = '_WEB' //用于区分存储值的标识，防止与客户端键名冲突
        if(callbackObj) {
            return callbackObj.getObj(key + identification)
        }
        else{
            return localStorage.getItem(key + identification)
        }
    } catch (error) {
        alert(error.toString)
    }
}

//删除存储到客户端的某个数据
function removeItem (key) {
    try{
        const identification = '_WEB' //用于区分存储值的标识，防止与客户端键名冲突
        if(callbackObj) {
            return callbackObj.delObj(key + identification)
        }else{
            return localStorage.removeItem(key + identification)
        }
    } catch (error) {
        alert(error.toString)
    }
}
//调用客户端批量下载
function batchDownload (list) {
    try{
        if(callbackObj) {
            list =  JSON.stringify(list)
            callbackObj.fileDownload(list)
        }else{
            CefSharp.BindObjectAsync('callbackObj') // 注册客户端api
        }
    } catch (error) {
        alert(error)
    }
}

// 打开客户端查看详情弹窗
// path 为客户端提供对应方法名，例: 工程概况 Com.Scrbg.Pcwp2.EngineeringView.EngineeringSummaryInfo.EditEngineeringSummaryInfoView
function openAppClientViewDetail (path, title, billId, isToDoTask) {
    try{
        callbackObj.changeLoadingState(true) // ChangeLoadingState为客户端提供打开loading的方法

        setTimeout(() => {
            callbackObj.changeLoadingState(false) // 调用客户端api关闭loading
            callbackObj.openWpfWindow(JSON.stringify({ Url: path, Title: title, Billid: billId, IsToDoTask: isToDoTask })) // OpenWindow为客户端提供打开弹窗的方法
        }, 1000)
    } catch (error) {
        alert(error.toString)
    }
}

// 公共弹窗
function showPromptPop (msg = '提示信息', callBack, cancelCallBack) {
    store.commit('setPopStatus', 'prompt')
    try{
        callbackObj.showGeneralMsgBox(msg)
        // 取消回调事件 客户端还未写
    } catch (e) {
        vm.$confirm(msg, '', {
            closeOnClickModal: false,
            closeOnPressEscape: false,
        })
            .then(callBack)
            .catch(cancelCallBack)
    }
    // 确认后恢复弹窗 false 状态
    store.commit('setPopConfirm', false)
}
function showSuccessPop (msg = '成功了', callBack, cancelCallBack) {
    store.commit('setPopStatus', 'success')
    try{
        callbackObj.showSuccessMsgBox(msg)
    } catch (e) {
        vm.$msgbox({
            type: 'success',
            closeOnClickModal: false,
            closeOnPressEscape: false,
            message: msg
        }).then(callBack)
            .catch(cancelCallBack)
    }
    // 确认后恢复弹窗 false 状态
    store.commit('setPopConfirm', false)
}
function showWarningPop (msg = '警告', callBack, cancelCallBack) {
    store.commit('warning', 'warn')
    try{
        callbackObj.showWarningMsgBox(msg)
    } catch (e) {
        vm.$msgbox({
            type: 'warning',
            closeOnClickModal: false,
            closeOnPressEscape: false,
            message: msg
        }).then(callBack)
            .catch(cancelCallBack)
    }
    // 确认后恢复弹窗 false 状态
    store.commit('setPopConfirm', false)
}
function showErrorPop (msg = '失败了', callBack, cancelCallBack) {
    store.commit('setPopStatus', 'error')
    try{
        callbackObj.showErrorMsgBox(msg)
    } catch (e) {
        vm.$msgbox({
            type: 'error',
            closeOnClickModal: false,
            closeOnPressEscape: false,
            message: msg
        }).then(callBack)
            .catch(cancelCallBack)
    }
    // 确认后恢复弹窗 false 状态
    store.commit('setPopConfirm', false)
}
function showErrorDetailPop (msg = '失败了', callBack, cancelCallBack, title = '接口调用失败') {
    store.commit('setPopStatus', 'errorDetail')
    try{
        callbackObj.showErrorMsgBoxEx(title, msg)
    } catch (e) {
        vm.$msgbox({
            type: 'error',
            closeOnClickModal: false,
            closeOnPressEscape: false,
            message: msg
        }).then(callBack)
            .catch(cancelCallBack)
    }
    // 确认后恢复弹窗 false 状态
    store.commit('setPopConfirm', false)
}

//客户端打印方法
function printReport (params) {
    // params =  {
    //     'ReportTitle': '报表名',
    //     'OrgName': '机构',
    //     'ReportQRUri': '报表内容URI',
    //     'BillNo': '单据编码',
    //     'SummaryInfoItems': [
    //         {
    //             'DisplayName': '标题：',
    //             'DisplayValue': '内容',
    //             'IsFullRow': true
    //         }
    //     ],
    //     'Tables': [
    //         {
    //             'TableTitle': '表名',
    //             'Header': [
    //                 '列头1',
    //                 '列头2'
    //             ],
    //             'TableRows': [
    //                 [
    //                     '内容1',
    //                     '内容2'
    //                 ],
    //                 [
    //                     '内容3',
    //                     '内容4'
    //                 ]
    //             ]
    //         }
    //     ]
    // }
    if (callbackObj) {
        callbackObj.printReport(JSON.stringify(params))
    } else {
        CefSharp.BindObjectAsync('callbackObj') // 注册客户端api
    }

}

function webprintReport (params) {
    // params =  {
    //     'reportTitle': '', //报表名
    //     'orgName': '', //单据机构
    //     'reportQRUri': '', //报表内容URI
    //     'billNo': '', //单据编码
    //     'summaryInfoItems': [ //基本信息
    //         {
    //             'label': '标题：',
    //             'value': '内容',
    //             'isFullRow': true //是否占整行
    //         },
    //         {
    //             'label': '标题1：',
    //             'value': '内容2',
    //             'isFullRow': true //是否占整行
    //         }
    //     ],
    //     'tables': [ //表格
    //         {
    //             'tableTitle': '表名',
    //             'tableContent': {
    //                 '表头1': '字段名',
    //                 '表头2': '字段名',
    //                 '表头3': '字段名',
    //             },
    //             'tableData': [], //表格数据
    //         }
    //     ]
    // }
    const sendParams = {
        'ReportTitle': '',
        'OrgName': '',
        'ReportQRUri': '',
        'BillNo': '',
        'SummaryInfoItems': [
        ],
        'Tables': [
        ]
    }
    const isNull = data=>{
        return (data !== null && data !== undefined)
    }
    sendParams.ReportTitle =  isNull(params.reportTitle) ? params.reportTitle : ''
    sendParams.OrgName = params.orgName ? params.orgName : ''
    sendParams.ReportQRUri = params.reportQRUri ? params.reportQRUri : window.location.href
    sendParams.BillNo = params.billNo ? params.billNo : ''
    params.summaryInfoItems.forEach(item=>{
        const obj = {}
        obj['DisplayName'] = isNull(item.label) ? item.label : ''
        obj['DisplayValue'] = isNull(item.value)  ? item.value : ''
        obj['IsFullRow'] = isNull(item.isFullRow) ? item.isFullRow : false
        sendParams.SummaryInfoItems.push(obj)
    })
    params.tables.forEach(item=>{
        const obj = {
            'TableTitle': '',
            'Header': [
            ],
            'TableRows': [
            ]
        }
        obj['TableTitle'] = isNull(item.tableTitle) ? item.tableTitle : ''
        obj['Header'] = Object.keys(item.tableContent)
        if( Array.isArray(item.tableData) && item.tableData.length > 0) {
            item.tableData.forEach(res=>{
                const arr = []
                for (const key in item.tableContent) {
                    arr.push( isNull(res[item.tableContent[key]]) ? res[item.tableContent[key]] : '' )
                }
                obj['TableRows'].push(arr)
            })
            sendParams.Tables.push(obj)
        }
    })
    console.log('🚀 ~ sendParams',  sendParams)
    printReport(sendParams)
}

// 随机19位数字
function random19Num (len) {
    len = len || 6
    let timestamp = new Date().getTime()
    let $chars = '1234567890'
    let maxPos = $chars.length
    let randomStr = ''
    for (let i = 0; i < len; i++) {
        randomStr += $chars.charAt(Math.floor(Math.random() * maxPos))
    }
    return randomStr + timestamp
}

// 数组对象剔重
function uniqueArray (arr, key) {
    const map = new Map()
    return arr.filter(item => !map.has(item[key] + '') && map.set(item[key] + '', 1))
}

// 定位到新添加行
function toLocation (addData) {
    let n = 0
    let si = setInterval(() => {
        n++
        const tr = document.querySelector(`.class-${addData.listId}`)
        if (tr) {
            const ipt = tr.querySelector('.el-input__inner')
            if (ipt) {
                clearInterval(si)
                si = null
                ipt.focus()
            } else {
                if (n > 5) {
                    clearInterval(si)
                    si = null
                }
            }
        } else {
            if (n > 5) {
                clearInterval(si)
                si = null
            }
        }
    }, 100)
}

// 操作dom
// fun为要执行的函数，junfun为判断条件返回布尔值
function vueDom (fun, jugFun) {
    Vue.nextTick(()=>{
        fun()
    })
    // 有可能还是获取不到dom
    const tempInterval = setInterval(() => {
        // 条件为true就跳出定时器
        if (!jugFun()) {
            fun()
        } else {
            clearInterval(tempInterval)
        }
    }, 100)
    // 防止异常
    setTimeout(() => {
        clearInterval(tempInterval)
    }, 1000)
}

//表格嵌套表单规则验证方法
function  validatorTable (ref, rules, tableData, _this, tableIndex) {
    /*
        ref:表格里表单ref前缀
        rules：表格里表单的rules
        tableData：表格平级数据
        _this:传入当前页面的vue实例对象
        tableIndex:当前tableIndex的字段名称
    */
    const data = {
        valid: false, //验证是否通过
        validMessage: [], //错误信息
        validMessageDetail: {}//错误信息的详情，包含哪一行哪个字段
    }
    let fieldsMesseges = []
    tableData.forEach((item, index)=>{
        let fields = []
        if(tableIndex) {
            _this[tableIndex] = index //给外部index赋值当索引，使外面定位当前行数据
        }
        for(let key in rules) {
            const ref = _this.$refs[ref + index + key]
            if(!ref) return
            const trigger =  [...new Set(rules[key].map(x=>x.trigger).flat())] //获取当前规则需要触发的事件名称扁平化并去重
            trigger.forEach(res=>{
                res = res.replace(res[0], res[0].toUpperCase()) //首字母转大写
                ref.fields[0]['onField' + res]() //触发对应验证的事件
            })
            fields = fields.concat(ref.fields)
        }
        const fieldsError = fields.filter(x=>x.validateState === 'error') //获取验证不通过的节点
        if(fieldsError.length > 0) {
            data.validMessageDetail[index] = fieldsError.map(x=>{ //添加详细错误信息
                return{ [x._props.prop]: x.validateMessage }
            })
        }
        const fieldsMessege = fieldsError.map(x=>x.validateMessage)
        fieldsMesseges = fieldsMesseges.concat(fieldsMessege)
        data.validMessage =  [...new Set(data.validMessage.concat(fieldsMessege))] //添加错误信息
    })
    if(fieldsMesseges.length > 0) {
        data.valid = false
    }else{
        data.valid = true
    }
    return data
}
//社会信用代码规则
function creditCode (creditCode) {
    function checkCreditCode (creditCode) {
        const secondarray = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'T', 'U', 'W', 'X', 'Y']
        //加权因子数值
        const secondkeys = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]
        //将信用代码中小写字母转成大写
        if (creditCode.length != 18) {
            return false
        }
        var reg = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/
        if (!reg.test(creditCode)) {
            return false
        }

        const parityBit = getParityBit(creditCode, secondkeys, secondarray)
        if(parityBit < 0) {
            return false
        }else{
            return creditCode.slice(17) === secondarray[parityBit]
        }
    }

    function getParityBit (code, secondkeys, secondarray) {
	        let sum = 0
        let i
        for(i = 0;i < 17;++i) {
            let codeIndex = secondarray.indexOf(code[i])
            if(codeIndex === -1) {
                return -1
            }
            sum += codeIndex * secondkeys[i]
        }
        i = 31 - sum % 31
        return i == 31 ? 0 : i
    }
    return checkCreditCode(creditCode)
}
//数字转大写中文
function numToChinese (n) {
    if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(n)) {
        return '数据非法' //判断数据是否大于0
    }
    let unit = '千百拾亿千百拾万千百拾元角分',
        str = ''
    n += '00'
    let indexpoint = n.indexOf('.') // 如果是小数，截取小数点前面的位数
    if (indexpoint >= 0) {
        n = n.substring(0, indexpoint) + n.substr(indexpoint + 1, 2) // 若为小数，截取需要使用的unit单位
    }
    unit = unit.substr(unit.length - n.length) // 若为整数，截取需要使用的unit单位
    for (let i = 0; i < n.length; i++) {
        str += '零壹贰叁肆伍陆柒捌玖'.charAt(n.charAt(i)) + unit.charAt(i) //遍历转化为大写的数字
    }

    return str
        .replace(/零(千|百|拾|角)/g, '零')
        .replace(/(零)+/g, '零')
        .replace(/零(万|亿|元)/g, '$1')
        .replace(/(亿)万|壹(拾)/g, '$1$2')
        .replace(/^元零?|零分/g, '')
        .replace(/元$/g, '元整') // 替换掉数字里面的零字符，得到结果
}
export {
    fileUrl,
    getUuid,
    getUrlParams,
    formatDate,
    formatFileSize,
    isPic,
    parseList,
    treeToList,
    getItemOfTreeArr,
    groupBy,
    copyTxt,
    autoClick,
    bytesToSize,
    debounce,
    throttle,
    showLoading,
    hideLoading,
    downloadFile,
    advanceSearch,
    showPromptPop,
    showSuccessPop,
    showErrorPop,
    selectDataClient,
    openAppClient,
    closeAppClient,
    openAppClientViewDetail,
    random19Num,
    uniqueArray,
    toLocation,
    vueDom,
    validatorTable,
    setItem,
    getItem,
    removeItem,
    batchDownload,
    creditCode,
    numToChinese,
    showErrorDetailPop,
    showWarningPop,
    printReport,
    webprintReport,
    showWebClient
}

